<template>
    <a-tree
        class="draggable-tree"
        default-expand-all
        draggable
        block-node
        :tree-data="data"
        v-model:selectedKeys="selectedKeys"
        @select="handleSelect"
    />
</template>
<script lang="ts">
import { defineComponent, inject, PropType, ref, watch } from "vue";
import { NodeAttrType } from "../../type/index";

const rex = ["a-modal", "a-drawer"];

interface TreeNodeType extends NodeAttrType {
    dataRef: NodeAttrType;
}

function map(tree: any[], cb?: Function) {
    for (let i = 0; i < tree.length; i++) {
        const item = tree[i];

        cb && cb(item);

        if (item.slot && Array.isArray(item.slot)) {
            map(item.slot, cb);
        }

        if (item.children && Array.isArray(item.children)) {
            map(item.children, cb);
        }
    }
}

function handleTree(tree: NodeAttrType[]): any {
    let modal: any = [];
    map(tree, (item: NodeAttrType) => {
        if (rex.includes(item.tag)) {
            modal.push(item);
        }
    });

    return modal;
}

export default defineComponent({
    props: {
        treeData: Object as PropType<NodeAttrType[] | undefined>,
    },
    setup(props) {
        const current = inject<any>("current");
        if (!props.treeData) {
            return {};
        }
        const modal = handleTree(props.treeData);
        const data = ref([...modal, ...props.treeData]);

        // 缓存数据
        let cache_obj: NodeAttrType | null = null;

        const handleSelect = (
            selectedKeys: string[],
            { selected, node }: { selected: boolean; node: TreeNodeType }
        ) => {
            const { dataRef } = node;
            if (rex.includes(dataRef.tag)) {
                node.dataRef.attributes.visible = selected;
                current.value = node.dataRef;

                cache_obj = dataRef;
            } else {
                if (cache_obj) {
                    cache_obj.attributes.visible = false;
                }
            }
        };

        const selectedKeys = ref<string[]>([]);

        if (current) {
            watch(
                () => current.value,
                (val) => {
                    selectedKeys.value = [val.key];
                }
            );
        }

        return { data, selectedKeys, handleSelect };
    },
});
</script>
